/*
 * Copyright (c) 2007-2011, Petr Panteleyev
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 *    1. Redistributions of source code must retain the above copyright notice,
 *       this list of conditions and the following disclaimer.
 *    2. Redistributions in binary form must reproduce the above copyright notice,
 *       this list of conditions and the following disclaimer in the documentation
 *       and/or other materials provided with the distribution.
 *    3. The name of the author may not be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package org.panteleyev.gclient;

import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ImageIcon;
import javax.swing.JFrame;

import org.panteleyev.blogapi.IBlogEntry;
import org.panteleyev.blogclient.BloggerFrame;
import org.panteleyev.blogclient.IPhotoUserProfile;
import org.panteleyev.blogclient.Icon;
import org.panteleyev.blogclient.MainClass;
import org.panteleyev.blogclient.ProfileDialog;
import org.panteleyev.blogclient.UserProfile;
import org.panteleyev.blogclient.UserProfileType;
import org.panteleyev.swing.OSUtil;
import org.panteleyev.swing.WindowManager;
import org.panteleyev.swing.WindowManagerEnumerator;

/**
 *
 * @author Petr Panteleyev
 */
public class GBUserProfile extends UserProfile<GBEntry> implements IPhotoUserProfile, Serializable {
    private final static long serialVersionUID = 20100206L;

    /* Serializable fields */
    private boolean commentsCountAutoLoad = false;
    private boolean convertLineBreaks = true;

    /* Transient fields */
    private transient GBAccount       account;
    private transient ArrayList<AbstractAction> toolBarActions;

    /* Actions */
    private transient AbstractAction      dashboardAction;
    private transient AbstractAction      historyWindowAction;
    private transient AbstractAction      albumsWindowAction;
    private transient ArrayList<AbstractAction> accountActions;

    /**
     * Creates a new instance of GBUserProfile
     * @param name
     */
    public GBUserProfile(String name, String server) {
        super(UserProfileType.GOOGLE, name, server);
        createActions();
    }

    private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException {
        stream.defaultReadObject();
        createActions();
    }

    public void setAccount(GBAccount account) {
        this.account = account;
    }

    public GBAccount getAccount() {
        return account;
    }

    public boolean getCommentCountAutoLoad() {
        return commentsCountAutoLoad;
    }

    public void setCommentCountAutoLoad(boolean b) {
        commentsCountAutoLoad = b;
    }

    public boolean isConvertLineBreaks() {
        return convertLineBreaks;
    }

    public void setConvertLineBreaks(boolean convertLineBreaks) {
        this.convertLineBreaks = convertLineBreaks;
    }

    @Override
    public ProfileDialog createProfileDialog(BloggerFrame frame) {
        return new GBProfileDialog(frame, this);
    }

    private void createActions() {
        dashboardAction = new AbstractAction(L10N.DASHBOARD_ACTION.s(), Icon.EARTH.i()) {
            @Override
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                OSUtil.runBrowser("http://www.blogger.com/home");
            }
        };
        dashboardAction.putValue(Action.LARGE_ICON_KEY, Icon.EARTH.I());

        historyWindowAction = new HistoryFrameAction();

        albumsWindowAction = new AbstractAction(L10N.ALBUMS_ACTION.s(), Icon.PICASA.i()) {
            @Override
            public void actionPerformed(java.awt.event.ActionEvent evt) { onAlbumsWindow(); }
        };
        albumsWindowAction.putValue(Action.LARGE_ICON_KEY, Icon.PICASA.I());

        accountActions = new ArrayList<>();
        accountActions.add(getNewPostAction());
        accountActions.add(null);
        accountActions.add(historyWindowAction);
        accountActions.add(albumsWindowAction);
        accountActions.add(null);
        accountActions.add(dashboardAction);

        toolBarActions = new ArrayList<>();
        toolBarActions.add(historyWindowAction);
        toolBarActions.add(albumsWindowAction);
    }

    @Override
    public ArrayList<AbstractAction> getProfileActions() {
        return accountActions;
    }

    @Override
    public String getProfileMenuName() {
        return L10N.BLOGSPOT_MENU_NAME.s();
    }

    @Override
    public ArrayList<AbstractAction> getProfileToolBarActions() {
        return toolBarActions;
    }

    @Override
    public boolean login(boolean store, final boolean offl) {
        account = new GBAccount();
        final String _uName = getUserName();
        final String _passwd = getPasswdTemp();
//        _offline = offl;
        setOnline(!offl);

        try {
            if (Thread.interrupted()) {
                return false;
            }

            if (!offl) {
                account.login(_uName, _passwd);

                /* Add more actions */
                ArrayList<GBlog> blogs = account.getBlogs();
                if (!blogs.isEmpty()) {
                    accountActions.add(null);
                    for (GBlog blog : blogs) {
                        final String blogUrl = blog.getBlogUrl().toString();
                        AbstractAction action = new AbstractAction(blog.getTitle(), Icon.EARTH.i()) {
                            @Override
                            public void actionPerformed(java.awt.event.ActionEvent evt) {
                                OSUtil.runBrowser(blogUrl);
                            }
                        };
                        accountActions.add(action);
                    }
                }
            } else {
            }
            if (Thread.interrupted()) {
                return false;
            }

            setAccount(account);
            setConnected(true);
            return true;
        } catch (Exception e) {
            MainClass.handleException(null, e);
            return false;
        }
    }

    @Override
    public void postLoginUIActions() {
        historyWindowAction.setEnabled((!account.getBlogs().isEmpty()) && isOnline());
        albumsWindowAction.setEnabled(isOnline());
        dashboardAction.setEnabled(isOnline());
    }

    @Override
    public void onNewPost() {
        new GBEditorFrame(this, null).setVisible(true);
    }

    private void onAlbumsWindow() {
        JFrame frame = findFrame(GPicasaGalleryFrame.class);
        if (frame != null) {
            frame.setVisible(true);
        } else {
            new GPicasaGalleryFrame(this).setVisible(true);
        }
    }

    @Override
    public void onHistoryFrameAction() {
        JFrame frame = findFrame(GBHistoryFrame.class);
        if (frame != null) {
            frame.setVisible(true);
        } else {
            new GBHistoryFrame(this).setVisible(true);
        }
    }

    public void openCommentsWindow(GBEntry entry) {
        GBCommentsFrame wnd = findCommentsWindowForPost(entry);
        if (wnd == null) {
            try {
                wnd = new GBCommentsFrame(this, entry);
            } catch (GBException e) {
                MainClass.handleException(null, e);
                return;
            }
        }
        wnd.setVisible(true);
    }

    public void openCommentEditWindow(GBEntry post) {
        GBCommentEditFrame wnd = findCommentEditWindow(post);
        if (wnd == null) {
            wnd = new GBCommentEditFrame(this, post);
        }
        wnd.setVisible(true);
    }

    public void addNewComment(GBComment comment) {
        GBCommentsFrame wnd = findCommentsWindowForPost(comment.getPost());
        if (wnd != null) {
            wnd.addNewComment(comment);
        } else {
            try {
                account.createComment(comment);
            } catch (Exception e) {
                MainClass.handleException(null, e);
            }
        }
    }

    @Override
    public GBEditorFrame findBlogEntryEditor(final GBEntry entry) {
        return WindowManager.find(GBEditorFrame.class, new WindowManagerEnumerator<GBEditorFrame>() {
            @Override
            public boolean frameFound(GBEditorFrame frame) {
                return (entry.equals(frame.getPost()));
            }
        });
    }

    public GBCommentsFrame findCommentsWindowForPost(final GBEntry post) {
        if (post == null) {
            return null;
        }

        return WindowManager.find(GBCommentsFrame.class, new WindowManagerEnumerator<GBCommentsFrame>() {
            @Override
            public boolean frameFound(GBCommentsFrame frame) {
                return post.equals(frame.getPost());
            }
        });
    }

    public GBCommentEditFrame findCommentEditWindow(final GBEntry post) {
        if (post == null) {
            return null;
        }

        return WindowManager.find(GBCommentEditFrame.class, new WindowManagerEnumerator<GBCommentEditFrame>() {
            @Override
            public boolean frameFound(GBCommentEditFrame frame) {
                return post.equals(frame.getPost());
            }
        });
    }

    @Override
    public String getImageCacheName() {
        return "picasa";
    }

    @Override
    public IBlogEntry newBlogEntry() {
        return new GBEntry();
    }

    @Override
    public void openBlogEntryEditor(GBEntry entry, File file) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void publishEntry(GBEntry entry) throws Exception {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void onOutboxFrameAction() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void updateEntryAdterRestore(GBEntry entry) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public ImageIcon getIcon() {
        return Icon.GOOGLE.i();
    }
}
